#include "mesh.h"

int mesh_malloc(Mesh *pMesh, int pVertexQty)
{
    /*    printf("mesh_malloc()\n"); */
    pMesh->vertex_qty = pVertexQty;
    pMesh->vertex = malloc(pVertexQty * sizeof(Vertex));

    if (pMesh->vertex == NULL)
    {
        fprintf(stderr, "Error allocating mesh memory\n");
        return 0;
    }

    return 1;
}

int mesh_free(Mesh *pMesh)
{
    /*    printf("mesh_free()\n"); */

    free(pMesh->vertex);

    return 1;
}

/**
 * This is just a hack to make a test model, will need to be replaced by a 3ds loader or some pretty maths
 */
int mesh_make_cube(Mesh *pMesh, int pSize)
{
    /*    printf("mesh_make_cube()\n"); */
    int i = 0;

    pMesh->poly_mode = GL_QUADS;
    if (!mesh_malloc(pMesh, 24))
    {
        fprintf(stderr, "Could not make cube mesh\n");
        return 0;
    }

    pMesh->vertex[i].nx = 0.0f;
    pMesh->vertex[i].ny = -1.0f;
    pMesh->vertex[i].nz = 0.0f;
    pMesh->vertex[i].u0 = 0.0f;
    pMesh->vertex[i].v0 = 0.0f;
    pMesh->vertex[i].x = -pSize;
    pMesh->vertex[i].y = -pSize;
    pMesh->vertex[i].z = -pSize;
    i++;

    pMesh->vertex[i].nx = 0.0f;
    pMesh->vertex[i].ny = -1.0f;
    pMesh->vertex[i].nz = 0.0f;
    pMesh->vertex[i].u0 = 1.0f;
    pMesh->vertex[i].v0 = 0.0f;
    pMesh->vertex[i].x = pSize;
    pMesh->vertex[i].y = -pSize;
    pMesh->vertex[i].z = -pSize;
    i++;

    pMesh->vertex[i].nx = 0.0f;
    pMesh->vertex[i].ny = -1.0f;
    pMesh->vertex[i].nz = 0.0f;
    pMesh->vertex[i].u0 = 1.0f;
    pMesh->vertex[i].v0 = 1.0f;
    pMesh->vertex[i].x = pSize;
    pMesh->vertex[i].y = -pSize;
    pMesh->vertex[i].z = pSize;
    i++;

    pMesh->vertex[i].nx = 0.0f;
    pMesh->vertex[i].ny = -1.0f;
    pMesh->vertex[i].nz = 0.0f;
    pMesh->vertex[i].u0 = 0.0f;
    pMesh->vertex[i].v0 = 1.0f;
    pMesh->vertex[i].x = -pSize;
    pMesh->vertex[i].y = -pSize;
    pMesh->vertex[i].z = pSize;
    i++;


    pMesh->vertex[i].nx = 0.0f;
    pMesh->vertex[i].ny = 1.0f;
    pMesh->vertex[i].nz = 0.0f;
    pMesh->vertex[i].u0 = 0.0f;
    pMesh->vertex[i].v0 = 0.0f;
    pMesh->vertex[i].x = -pSize;
    pMesh->vertex[i].y = pSize;
    pMesh->vertex[i].z = -pSize;
    i++;

    pMesh->vertex[i].nx = 0.0f;
    pMesh->vertex[i].ny = 1.0f;
    pMesh->vertex[i].nz = 0.0f;
    pMesh->vertex[i].u0 = 1.0f;
    pMesh->vertex[i].v0 = 0.0f;
    pMesh->vertex[i].x = pSize;
    pMesh->vertex[i].y = pSize;
    pMesh->vertex[i].z = -pSize;
    i++;

    pMesh->vertex[i].nx = 0.0f;
    pMesh->vertex[i].ny = 1.0f;
    pMesh->vertex[i].nz = 0.0f;
    pMesh->vertex[i].u0 = 1.0f;
    pMesh->vertex[i].v0 = 1.0f;
    pMesh->vertex[i].x = pSize;
    pMesh->vertex[i].y = pSize;
    pMesh->vertex[i].z = pSize;
    i++;

    pMesh->vertex[i].nx = 0.0f;
    pMesh->vertex[i].ny = 1.0f;
    pMesh->vertex[i].nz = 0.0f;
    pMesh->vertex[i].u0 = 0.0f;
    pMesh->vertex[i].v0 = 1.0f;
    pMesh->vertex[i].x = -pSize;
    pMesh->vertex[i].y = pSize;
    pMesh->vertex[i].z = pSize;
    i++;


    pMesh->vertex[i].nx = -1.0f;
    pMesh->vertex[i].ny = 0.0f;
    pMesh->vertex[i].nz = 0.0f;
    pMesh->vertex[i].u0 = 0.0f;
    pMesh->vertex[i].v0 = 0.0f;
    pMesh->vertex[i].x = -pSize;
    pMesh->vertex[i].y = -pSize;
    pMesh->vertex[i].z = -pSize;
    i++;

    pMesh->vertex[i].nx = -1.0f;
    pMesh->vertex[i].ny = 0.0f;
    pMesh->vertex[i].nz = 0.0f;
    pMesh->vertex[i].u0 = 0.0f;
    pMesh->vertex[i].v0 = 1.0f;
    pMesh->vertex[i].x = -pSize;
    pMesh->vertex[i].y = -pSize;
    pMesh->vertex[i].z = pSize;
    i++;

    pMesh->vertex[i].nx = -1.0f;
    pMesh->vertex[i].ny = 0.0f;
    pMesh->vertex[i].nz = 0.0f;
    pMesh->vertex[i].u0 = 1.0f;
    pMesh->vertex[i].v0 = 1.0f;
    pMesh->vertex[i].x = -pSize;
    pMesh->vertex[i].y = pSize;
    pMesh->vertex[i].z = pSize;
    i++;

    pMesh->vertex[i].nx = -1.0f;
    pMesh->vertex[i].ny = 0.0f;
    pMesh->vertex[i].nz = 0.0f;
    pMesh->vertex[i].u0 = 1.0f;
    pMesh->vertex[i].v0 = 0.0f;
    pMesh->vertex[i].x = -pSize;
    pMesh->vertex[i].y = pSize;
    pMesh->vertex[i].z = -pSize;
    i++;


    pMesh->vertex[i].nx = 1.0f;
    pMesh->vertex[i].ny = 0.0f;
    pMesh->vertex[i].nz = 0.0f;
    pMesh->vertex[i].u0 = 0.0f;
    pMesh->vertex[i].v0 = 0.0f;
    pMesh->vertex[i].x = pSize;
    pMesh->vertex[i].y = -pSize;
    pMesh->vertex[i].z = -pSize;
    i++;

    pMesh->vertex[i].nx = 1.0f;
    pMesh->vertex[i].ny = 0.0f;
    pMesh->vertex[i].nz = 0.0f;
    pMesh->vertex[i].u0 = 0.0f;
    pMesh->vertex[i].v0 = 1.0f;
    pMesh->vertex[i].x = pSize;
    pMesh->vertex[i].y = -pSize;
    pMesh->vertex[i].z = pSize;
    i++;

    pMesh->vertex[i].nx = 1.0f;
    pMesh->vertex[i].ny = 0.0f;
    pMesh->vertex[i].nz = 0.0f;
    pMesh->vertex[i].u0 = 1.0f;
    pMesh->vertex[i].v0 = 1.0f;
    pMesh->vertex[i].x = pSize;
    pMesh->vertex[i].y = pSize;
    pMesh->vertex[i].z = pSize;
    i++;

    pMesh->vertex[i].nx = 1.0f;
    pMesh->vertex[i].ny = 0.0f;
    pMesh->vertex[i].nz = 0.0f;
    pMesh->vertex[i].u0 = 1.0f;
    pMesh->vertex[i].v0 = 0.0f;
    pMesh->vertex[i].x = pSize;
    pMesh->vertex[i].y = pSize;
    pMesh->vertex[i].z = -pSize;
    i++;


    pMesh->vertex[i].nx = 0.0f;
    pMesh->vertex[i].ny = 0.0f;
    pMesh->vertex[i].nz = -1.0f;
    pMesh->vertex[i].u0 = 0.0f;
    pMesh->vertex[i].v0 = 0.0f;
    pMesh->vertex[i].x = -pSize;
    pMesh->vertex[i].y = -pSize;
    pMesh->vertex[i].z = -pSize;
    i++;

    pMesh->vertex[i].nx = 0.0f;
    pMesh->vertex[i].ny = 0.0f;
    pMesh->vertex[i].nz = -1.0f;
    pMesh->vertex[i].u0 = 0.0f;
    pMesh->vertex[i].v0 = 1.0f;
    pMesh->vertex[i].x = -pSize;
    pMesh->vertex[i].y = pSize;
    pMesh->vertex[i].z = -pSize;
    i++;

    pMesh->vertex[i].nx = 0.0f;
    pMesh->vertex[i].ny = 0.0f;
    pMesh->vertex[i].nz = -1.0f;
    pMesh->vertex[i].u0 = 1.0f;
    pMesh->vertex[i].v0 = 1.0f;
    pMesh->vertex[i].x = pSize;
    pMesh->vertex[i].y = pSize;
    pMesh->vertex[i].z = -pSize;
    i++;

    pMesh->vertex[i].nx = 0.0f;
    pMesh->vertex[i].ny = 0.0f;
    pMesh->vertex[i].nz = -1.0f;
    pMesh->vertex[i].u0 = 1.0f;
    pMesh->vertex[i].v0 = 0.0f;
    pMesh->vertex[i].x = pSize;
    pMesh->vertex[i].y = -pSize;
    pMesh->vertex[i].z = -pSize;
    i++;


    pMesh->vertex[i].nx = 0.0f;
    pMesh->vertex[i].ny = 0.0f;
    pMesh->vertex[i].nz = 1.0f;
    pMesh->vertex[i].u0 = 0.0f;
    pMesh->vertex[i].v0 = 0.0f;
    pMesh->vertex[i].x = -pSize;
    pMesh->vertex[i].y = -pSize;
    pMesh->vertex[i].z = pSize;
    i++;

    pMesh->vertex[i].nx = 0.0f;
    pMesh->vertex[i].ny = 0.0f;
    pMesh->vertex[i].nz = 1.0f;
    pMesh->vertex[i].u0 = 0.0f;
    pMesh->vertex[i].v0 = 1.0f;
    pMesh->vertex[i].x = -pSize;
    pMesh->vertex[i].y = pSize;
    pMesh->vertex[i].z = pSize;
    i++;

    pMesh->vertex[i].nx = 0.0f;
    pMesh->vertex[i].ny = 0.0f;
    pMesh->vertex[i].nz = 1.0f;
    pMesh->vertex[i].u0 = 1.0f;
    pMesh->vertex[i].v0 = 1.0f;
    pMesh->vertex[i].x = pSize;
    pMesh->vertex[i].y = pSize;
    pMesh->vertex[i].z = pSize;
    i++;

    pMesh->vertex[i].nx = 0.0f;
    pMesh->vertex[i].ny = 0.0f;
    pMesh->vertex[i].nz = 1.0f;
    pMesh->vertex[i].u0 = 1.0f;
    pMesh->vertex[i].v0 = 0.0f;
    pMesh->vertex[i].x = pSize;
    pMesh->vertex[i].y = -pSize;
    pMesh->vertex[i].z = pSize;
    i++;

    return 1;
}

int draw_mesh(Mesh *pMesh)
{
    int i;

    glBegin(pMesh->poly_mode);
    for (i = 0; i < pMesh->vertex_qty; i++)
    {
        glNormal3fv(&pMesh->vertex[i].nx);
        glTexCoord2fv(&pMesh->vertex[i].u0);
        glVertex3fv(&pMesh->vertex[i].x);
    }
    glEnd();

    return 1;
}
